% -*- Mode: LaTeX; Package: CLIM-USER -*-

\chapter {Application Frames}
\label {application-frames}

\section {Overview of Application Frames}

\concept{Application frames} (or simply, \concept{frames}) are the central
abstraction defined by CLIM for presenting an application's user interface.
Many of the other features and facilities provided by CLIM (for example, the
generic command loop, gadgets, look and feel independence) can be conveniently
accessed through the frame facility.  Frames can be displayed as either
top-level windows or regions embedded within the space of the user interfaces of
other applications.  In addition to controlling the screen real estate managed
by an application, a frame keeps track of the Lisp state variables that contain
the state of the application.

The visual aspect of an application frame is established by defining a hierarchy
of \concept{panes}.  CLIM panes are interactive objects that are analogous to
the windows, gadgets, or widgets of other toolkits.  Application builders can
compose their application's user interface from a library of standard panes or
by defining and using their own pane types.  Application frames can use a number
of different types of panes including \concept{layout panes} for spatially
organizing panes, \concept{user panes} for presenting application specific
information, and \concept{gadget panes} for displaying data and obtaining user
input.  Panes are describe in greater detail in Chapter~\ref{panes} and
Chapter~\ref{gadgets}.

Frames are managed by special applications called \concept{frame managers}.
Frame managers control the realization of the look and feel of a frame.  The
frame manager interprets the specification of the application frame in the
context of the available window system facilities, taking into account
preferences expressed by the user.  In addition, the frame manager takes care of
attaching the pane hierarchy of an application frame to an appropriate place in
a window hierarchy.  The most common type of frame manager is one that allows
the user to manipulate the frames of other applications.  This type of
application is typically called a desktop manager, or in X Windows terminology,
a window manager.  In many cases, the window manager will be a non-Lisp
application.  In these cases, the frame manager will act as a mediator between
the Lisp application and the host desktop manager.

Some applications may act as frame managers that allow the frames of other
applications to be displayed with their own frames.  For example, a text editor
might allow figures generated by a graphic editor to be edited in place by
managing the graphics editor's frame within its own frame.

Application frames provide support for a standard interaction processing loop,
like the Lisp ``read-eval-print'' loop, called a \concept{command loop}.  The
application programmer has to write only the code that implements the
frame-specific commands and output display functions.  A key aspect of the
command loop is the separation of the specification of the frame's commands from
the specification of the end-user interaction style.

The standard interaction loop consists of reading an input ``sentence'' (the
command and all of its operands), executing the command, and updating the
displayed information as appropriate.  CLIM implementations are free to run the
display update part of the loop at a lower priority than command execution, for
example, some implementations may choose not to update the display if there is
typed-ahead input.  Note that by default command execution and display will not
occur simultaneously, so user-defined functions need not have to cope with
multiprocessing.  Of course, the programmer can use multiple processes, but CLIM
neither directly supports nor precludes doing so.

To write an application that uses the standard interaction loop provided by
CLIM, an application programmer does the following:

\begin{itemize}
\item Defines the presentation types that correspond to the user interface
entities of the application.

\item Defines the commands that correspond to the visible operations of the
application, specifying the presentation types of the operands involved in each
command.

\item Defines the set of frames and panes needed to support the application.

\item Defines the output display functions associated with each of the panes
(possibly using other facilities such as the incremental redisplay).
\end{itemize}

Taking as an example a simple ECAD program, the programmer would first define
the appropriate presentation types, such as wires, input and output signals,
gates, resistors, and so forth.  He would then define the program's commands in
terms of these types.  For example, the ``Connect'' command might take two
operands, one of type ``component'' and the other of type ``wire''.  The
programmer may wish to specify the interaction style for invoking each command,
for example, direct manipulation via translators, or selection of commands from
menus.  After defining an application frame that includes a CLIM stream pane,
the programmer then writes the frame-specific display routine that displays the
circuit layout.  Now the application is ready to go.  The end-user selects a
command (via a menu or command-line, or whatever), the top-level loop takes care
of collecting the operands for that command (via a variety of user gestures),
and then the application invokes the command.  The command may have a
side-effect on the frame's ``database'' of information, which can in turn affect
the output displayed by the redisplay phase.

Note that this definition of the standard interaction loop does not constrain
the interaction style to be a command-line interface.  The input sentence may be
entered via single keystrokes, pointer input, menu selection, dialogs, or by
typing full command lines.


\section {Defining and Creating Application Frames}

\Defprotoclass {application-frame}

The protocol class that corresponds to an application frame.
\IfYouWantClass {an} {application frame} {application-frame}

All application frame classes are mutable.

\Defpredicate {application-frame-p} {object}

Returns \term{true} if \arg{object} is an \term{application frame}, otherwise
returns \term{false}.

\definitarg {:name}
\definitarg {:pretty-name}
\definitarg {:command-table}
\definitarg {:disabled-commands}
\definitarg {:panes}
\definitarg {:menu-bar}
\definitarg {:calling-frame}
\definitarg {:state}
\Definitarg {:properties}

All subclasses of \cl{application-frame} must handle these initargs, which are
used to specify, respectively, the name, pretty name, command table, initial set
of disabled commands, the panes, the menu bar, calling frame, state, and initial
properties for the frame.

\Defclass {standard-application-frame}

The instantiable standard class that implements application frames.  By default,
most application frame classes will inherit from this class, unless a
non-\cl{nil} value for \arg{superclasses} is supplied to \cl{define-application-frame}.


\Defmacro {define-application-frame} {name superclasses slots \rest options}

Defines a frame and CLOS class named by the symbol \arg{name} that inherits from
\arg{superclasses} and has state variables specified by \arg{slots}.
\arg{superclasses} is a list of superclasses that the new class will inherit
from (as in \cl{defclass}).  When \arg{superclasses} is \cl{nil}, it behaves as
though a superclass of \cl{standard-application-frame} was supplied.
\arg{slots} is a list of additional slot specifiers, whose syntax is the same as
the slot specifiers in \cl{defclass}.  Each instance of the frame will have
slots as specified by these slot specifiers.  These slots will typically hold
any per-instance frame state.

\arg{options} is a list of \cl{defclass}-style options, and can include the
usual \cl{defclass} options, plus any of the following:

\begin{itemize}
\item \cl{:pane} \arg{form}, where \arg{form} specifies the single pane in the
application.  The default is \cl{nil}, meaning that there is no single pane.
This is the simplest way to define a pane hierarchy.  The \cl{:pane} option is
mutually exclusive with the \cl{:panes} options.  See Section~\ref{frame-panes}
for a complete description of the \cl{:pane} option.

\item \cl{:panes} \arg{form}, where \arg{form} is an alist that specifies names
and panes of the application.  The default is \cl{nil}, meaning that there are
no named panes.  The \cl{:panes} and \cl{:pane} options are mutually exclusive.
See Section~\ref{frame-panes} for a complete description of the \cl{:panes}
option.

\item \cl{:layouts} \arg{form}, where \arg{form} specifies the layout.  The
default layout is to lay out all of the named panes in horizontal strips.  See
Section~\ref{frame-panes} for a complete description of the \cl{:layouts}
option.

\item \cl{:command-table} \arg{name-and-options}, where \arg{name-and-options}
is a list consisting of the name of the application frame's command table
followed by some keyword-value pairs.  The keywords can be \cl{:inherit-from} or
\cl{:menu} (which are as in \cl{define-command-table}).  The default is to
create a command table with the same name as the application frame.

\item \cl{:command-definer} \arg{value}, where \arg{value} either \cl{nil},
\cl{t}, or another symbol.  When it is \cl{nil}, no command-defining macro is
defined.  When it is \cl{t}, a command-defining macro is defined, whose name is
of the form \cl{define-{\it name}-command}.  When it is another symbol, the
symbol names the command-defining macro.  The default is \cl{t}.

\item \cl{:menu-bar} \arg{form} is used to specify what commands will appear
in a ``menu bar''.  It typically specifies the top-level commands of the
application.  \arg{form} is either \cl{nil}, meaning there is no menu bar;
\cl{t}, meaning that the menu from frame's command table (from the
\cl{:command-table} option) should be used; a symbol that names a command table,
meaning that that command table's menu should be used; or a list, which is
interpreted the same way the \cl{:menu} option to \cl{define-command-table} is
interpreted.  The default is \cl{t}.

\item \cl{:disabled-commands} \arg{commands}, where \arg{commands} is a list of
command names that are initially disabled in the application frame.  The set of
enabled and disabled commands can be modified via \cl{(setf~command-enabled)}.

\item \cl{:top-level} \arg{form}, where \arg{form} is a list whose first
element is the name of a function to be called to execute the top-level loop.
The function must take at least one argument, the frame.  The rest of the list
consists of additional arguments to be passed to the function.  The default
function is \cl{default-frame-top-level}.

\item \cl{:icon} \arg{pattern} specifies an array pattern to be
displayed by the host's window manager to visually enhance or
represent the frame, for example when it is iconified.

\item \cl{:geometry} \arg{plist}, where \arg{plist} is a property list
containing the default values for the \cl{:left}, \cl{:top}, \cl{:right},
\cl{:bottom}, \cl{:width}, and \cl{:height} options to
\cl{make-application-frame}.
\end{itemize}

The \arg{name}, \arg{superclasses}, and \arg{slots} arguments are not evaluated.
The values of each of the options are evaluated.


\Defun {make-application-frame} {frame-name \rest options
                                 \key pretty-name
                                      frame-manager enable state
                                      left top right bottom width height
                                      save-under frame-class
                                 \allow}

Makes an instance of the application frame of type \arg{frame-class}.  If
\arg{frame-class} is not supplied, it defaults to \arg{frame-name}.

The size options \arg{left}, \arg{top}, \arg{right}, \arg{bottom}, \arg{width},
and \arg{height} can be used to specify the initial size of the frame.  If they
are unsupplied and \cl{:geometry} was supplied to \cl{define-application-frame},
then these arguments default from the specified geometry.

\arg{options} are passed as additional arguments to \cl{make-instance}, after
the \arg{pretty-name}, \arg{frame-manager}, \arg{enable}, \arg{state},
\arg{save-under}, \arg{frame-class}, and size options have been removed.

If \arg{save-under} is \term{true}, then the sheets used to implement the user
interface of the frame will have the ``save under'' property, if the host window
system supports it.

If \arg{frame-manager} is provided, then the frame is adopted by the specified
frame manager.  If the frame is adopted and either of \arg{enable} or
\arg{state} are provided, the frame is pushed into the given state.

Once a frame has been create, \cl{run-frame-top-level} can be called to make the
frame visible and run its top-level function.

\Defvar {*application-frame*}

The current application frame.  The global value is CLIM's default application,
which serves only as a repository for whatever internal state is needed by CLIM
to operate properly.  This variable is typically used in the bodies of command
to gain access to the state variables of the application frame, usually in
conjunction with \cl{with-slots} or \cl{slot-value}.

\Defmacro {with-application-frame} {(frame) \body body}

This macro provides lexical access to the ``current'' frame for use with
commands and the \cl{:pane}, \cl{:panes}, and \cl{:layouts} options.
\arg{frame} is bound to the current frame within the context of one of those
options.

\arg{frame} is a symbol; it is not evaluated.  \arg{body} may have zero or more
declarations as its first forms.

\Defun {map-over-frames} {function \key port frame-manager}

Applies the function \arg{function} to all of the application frames that
``match'' \arg{port} and \arg{frame-manager}.  If neither \arg{port} nor
\arg{frame-manager} is supplied, all frames are considered to match.  If
\arg{frame-manager} is supplied, only those frames that use that frame manager
match.  If \arg{port} is supplied, only those frames that use that port match.

\arg{function} is a function of one argument, the frame.  It has dynamic extent.


\Defgeneric {destroy-frame} {frame}

Destroys the application frame \arg{frame}.

\Defgeneric {raise-frame} {frame}

Raises the application frame \arg{frame} to be on top of all of the other host
windows by invoking \cl{raise-sheet} on the frame's top-level sheet.

\Defgeneric {bury-frame} {frame}

Buries the application frame \arg{frame} to be underneath all of the other host
windows by invoking \cl{bury-sheet} on the frame's top-level sheet.


\subsection {Specifying the Panes of a Frame\label{frame-panes}}

The panes of a frame can be specified in one of two different ways.  If the
frame has a single layout and no need of named panes, then the \cl{:pane} option
can be used.  Otherwise if named panes or multiple layouts are required, the
\cl{:panes} and \cl{:layouts} options can be used.  Note that the \cl{:pane}
option is mutually exclusive with \cl{:panes} and \cl{:layouts}.   It is
meaningful to define frames that have no panes at all; the frame will simply
serve as a repository for state and commands.

Panes and gadgets are discussed in detail in Chapter~\ref{panes} and
Chapter~\ref{gadgets}.

The value of the \cl{:pane} option is a form that is used to create a single
(albeit arbitrarily complex) pane.  For example:

\begin{verbatim}
(vertically ()
  (tabling ()
    ((horizontally ()
       (make-pane 'toggle-button)
       (make-pane 'toggle-button)
       (make-pane 'toggle-button))
     (make-pane 'text-field))
    ((make-pane 'push-button :label "a button")
     (make-pane 'slider)))
  (scrolling ()
    (make-pane 'application-pane
               :display-function 'a-display-function))
  (scrolling ()
    (make-pane 'interactor-pane)))
\end{verbatim}

If the \cl{:pane} option is not used, a set of named panes can be specified with
the \cl{:panes} option.  Optionally, \cl{:layouts} can also be used to describe
different layouts of the set of panes.

The value of the \cl{:panes} option is a list, each entry of which is of the
form \arg{(name . body)}.  \arg{name} is a symbol that names the pane, and
\arg{body} specifies how to create the pane.  \arg{body} is either a list
containing a single element that is itself a list, or a list consisting of a
symbol followed by zero or more keyword-value pairs.  In the first case, the
\arg{body} is a form exactly like the form used in the \cl{:pane} option.  In
the second case, \arg{body} is a \concept{pane abbreviation} where the initial
symbol names the type of pane, and the keyword-value pairs are pane options.
For gadgets, the pane type is the class name of the abstract gadget (for
example, \cl{slider} or \cl{push-button}).  For CLIM stream panes, the following
abbreviations are defined:

\begin{itemize}
\item \cl{:interactor}---a pane of type \cl{interactor-pane}.

\item \cl{:application}---a pane of type \cl{application-pane}.

\item \cl{:command-menu}---a pane of type \cl{command-menu-pane}.

\item \cl{:pointer-documentation}---a pane suitable for displaying pointer
documentation, if the host window system does not provide this.

\item \cl{:title}---a pane suitable for displaying the title of the application,
if the host window system does not provide this.

\item \cl{:accept-values}---a pane that can hold a ``modeless''
\cl{accepting-values} dialog.
\end{itemize}

See Chapter~\ref{panes} and Chapter~\ref{gadgets} for more information on the
individual pane and gadget classes, and the options they support.

An example of the use of \cl{:panes} is:

\begin{verbatim}
(:panes
  (buttons (horizontally ()
             (make-pane 'push-button :label "Press me")
             (make-pane 'push-button :label "Squeeze me")))
  (toggle toggle-button
          :label "Toggle me")
  (interactor :interactor
              :width 300 :height 300)
  (application :application
               :display-function 'another-display-function
               :incremental-redisplay t))
\end{verbatim}

The value of the \cl{:layouts} option is a list, each entry of which is of the
form \arg{(name layout)}.  \arg{name} is a symbol that names the layout, and
\arg{layout} specifies the layout.  \arg{layout} is a form like the form used in
the \cl{:pane} option, with the extension to the syntax such that the name of a
named pane can be used wherever a pane may appear.  (This will typically be
implemented by using \cl{symbol-macrolet} for each of the named panes.)  For
example, assuming a frame that uses the \cl{:panes} example above, the following
layouts could be specified:

\begin{verbatim}
(:layouts
  (default
    (vertically ()
      button toggle
      (scrolling () application)
      interactor))
  (alternate
    (vertically ()
      (scrolling () application)
      (scrolling () interactor)
      (horizontally ()
        button toggle))))
\end{verbatim}

The syntax for \cl{:layouts} can be concisely expressed as:

\begin{description}
\item \cl{:layouts (\arg{layout-name layout-panes})}

\item \arg{layout-name} is a symbol.

\item \arg{layout-panes} is \arg{layout-panes1} or \cl{(\arg{size-spec layout-panes1})}.

\item \arg{layout-panes1} is a \arg{pane-name}, or a \arg{layout-macro-form}, or
\arg{layout-code}.

\item \arg{layout-code} is lisp code that generates a pane, which may include
the name of a named pane.

\item \arg{size-spec} is a rational number less than 1, or \cl{:fill}, or
\cl{:compute}.

\item \arg{layout-macro-form} is \cl{(\arg{layout-macro-name} (\arg{options}) .
\arg{body})}.

\item \arg{layout-macro-name} is one of the layout macros, such as
\cl{outlining}, \cl{spacing}, \cl{labelling}, \cl{vertically}, \cl{horizontally},
or \cl{tabling}.
\end{description}


\section {Application Frame Functions}

The generic functions described in this section are the functions that can be
used to read or modify the attributes of a frame.  All classes that inherit from
\cl{application-frame} must inherit or implement methods for all of these
functions.

\Defgeneric {frame-name} {frame}

Returns the name of the \term{frame} \arg{frame}, which is a symbol.

\Defgeneric {frame-pretty-name} {frame}

Returns the ``pretty name'' of the \term{frame} \arg{frame}, which is a string.

\Defgeneric {(setf frame-pretty-name)} {name frame}

Sets the pretty name of the \term{frame} \arg{frame} to \arg{name}, which must
be a string.  Changing the pretty name of a frame notifies its frame manager,
which in turn may change some aspects of the appearance of the frame, such as
its title bar.


\Defgeneric {frame-command-table} {frame}

Returns the command table for the \term{frame} \arg{frame}.

\Defgeneric {(setf frame-command-table)} {command-table frame}

Sets the command table for the \term{frame} \arg{frame} to \arg{command-table}.
Changing the frame's command table will redisplay the command menus (or menu
bar) as needed.  \arg{command-table} is a \term{command table designator}.


\Defgeneric {frame-standard-output} {frame}

Returns the stream that will be used for \cl{*standard-output*} for the
\term{frame} \arg{frame}.  The default method (on
\cl{standard-application-frame}) returns the first named pane of type
\cl{application-pane} that is visible in the current layout; if there is no such
pane, it returns the first pane of type \cl{interactor-pane} that is exposed in
the current layout.

\Defgeneric {frame-standard-input} {frame}

Returns the stream that will be used for \cl{*standard-input*} for the
\term{frame} \arg{frame}.  The default method (on
\cl{standard-application-frame}) returns the first named pane of type
\cl{interactor-pane} that is visible in the current layout; if there is no such
pane, the value returned by {frame-standard-output} is used.

\Defgeneric {frame-query-io} {frame}

Returns the stream that will be used for \cl{*query-io*} for the \term{frame}
\arg{frame}.  The default method (on \cl{standard-application-frame}) returns
the value returned by \cl{frame-standard-input}; if that is \cl{nil}, it returns
the value returned by \cl{frame-standard-output}.

\Defgeneric {frame-error-output} {frame}

Returns the stream that will be used for \cl{*error-output*} for the
\term{frame} \arg{frame}.  The default method (on
\cl{standard-application-frame}) returns the same value as
\cl{frame-standard-output}.

\Defvar {*pointer-documentation-output*}

This will be bound either to \cl{nil} or to a stream on which pointer
documentation will be displayed.

\Defgeneric {frame-pointer-documentation-output} {frame}

Returns the stream that will be used for \cl{*pointer-documentation-output*}
for the \term{frame} \arg{frame}.  The default method (on
\cl{standard-application-frame}) returns the first pane of type
\cl{pointer-documentation-pane}.  If this returns \cl{nil}, no pointer
documentation will be generated for this frame.


\Defgeneric {frame-calling-frame} {frame}

Returns the application frame that invoked the \term{frame} \arg{frame}.

\Defgeneric {frame-parent} {frame}

Returns the object that acts as the parent for the \term{frame} \arg{frame}.
This often, but not always, returns the same value as \cl{frame-manager}.


\Defgeneric {frame-panes} {frame}

Returns the pane that is the top-level pane in the current layout of the
\term{frame} \arg{frame}'s named panes.  This will typically be some sort of a
layout pane.

\Defgeneric {frame-top-level-sheet} {frame}

Returns the sheet that is the top-level sheet for the \term{frame} \arg{frame}.
This is the sheet that has as its descendents all of the panes of \arg{frame}.

The value returned by \cl{frame-panes} will be a descendents of the value of
\cl{frame-top-level-sheet}.

\Defgeneric {frame-current-panes} {frame}

Returns a list of those named panes in the \term{frame} \arg{frame}'s current
layout.  If there are no named panes (for example, the \cl{:pane} option was used),
only the single, top level pane is returned.
\ReadOnly

\Defgeneric {get-frame-pane} {frame pane-name}

Returns the named CLIM stream pane in the \term{frame} \arg{frame} whose name is
\arg{pane-name}.

\Defgeneric {find-pane-named} {frame pane-name}

Returns the pane in the \term{frame} \arg{frame} whose name is \arg{pane-name}.
This can return any type of pane, not just CLIM stream panes.


\Defgeneric {frame-current-layout} {frame}

Returns the current layout for the \term{frame} \arg{frame}.  The layout is
named by a symbol.

\Defgeneric {(setf frame-current-layout)} {layout frame}

Sets the layout of the \term{frame} \arg{frame} to be the new layout specified
by \arg{new-layout}.  \arg{layout} must be a symbol that names one of the
possible layouts.

Changing the layout of the frame must recompute what panes are used for the
bindings of the standard stream variables (such as \cl{*standard-input*}).  Some
implementations of CLIM may cause the application to ``throw'' all the way back
to \cl{run-frame-top-level} in order to do this.  After the new layout has been
computed, the contents of each of the panes must be displayed to the degree
necessary to ensure that all output is visible.

\Defgeneric {frame-all-layouts} {frame}

Returns a list of the names of all of the possible layouts for the frame.

\Defgeneric {layout-frame} {frame \optional width height}

Resizes the frame and lays out the current pane hierarchy using the layout
specified by \cl{frame-current-layout}, according to the layout protocol.  The
basics of the layout protocols are described in Section~\ref{layout-protocol}.
This function is automatically invoked on a frame when it is adopted, after its
pane hierarchy has been generated.

If \arg{width} and \arg{height} are provided, then this function resizes the
frame to the specified size.  It is an error to provide just \arg{width}.

If no optional arguments are provided, this function resizes the frame to the
preferred size of the top-level pane as determined by the space composition pass
of the layout protocol.

In either case, after the frame is resized, the space allocation pass of the
layout protocol is invoked on the top-level pane.


\Defcondition {frame-exit}

The condition that is signalled when \cl{frame-exit} is called.  This condition
will handle the \cl{:frame} initarg, which is used to supply the frame that is
being exited from.

\Defgeneric {frame-exit-frame} {condition}

Returns the frame that is being exited from associated with the \cl{frame-exit}
condition.

\Defgeneric {frame-exit} {frame}

Exits from the \term{frame} \arg{frame}.  The default method (on
\cl{standard-application-frame}) signals a \cl{frame-exit} condition, supplying
\arg{frame} as the \cl{:frame} initarg.


\Defgeneric {pane-needs-redisplay} {pane}

Returns two values, the first indicating whether the \term{pane} \arg{pane}
needs to be redisplayed, and the second indicating whether the pane needs to be
cleared before being redisplayed.  The first value is \term{true} when the pane
is to be redisplayed.  The second value is \term{true} when the pane is to be
cleared.

\Defgeneric {(setf pane-needs-redisplay)} {value pane}

Indicates that the \term{pane} \arg{pane} should (or should not) be redisplayed
the next time the owning frame executes the redisplay part of its command loop.

When \arg{value} is \cl{nil}, the pane will not require redisplay.  When
\arg{value} is \cl{t}, the pane will be cleared and redisplayed exactly once.
When \arg{value} is \cl{:command-loop}, the pane will be cleared and redisplayed
in each successive pass through the command loop.  When \arg{value} is
\cl{:no-clear}, the pane will be redisplayed exactly once without clearing it.

\Defgeneric {redisplay-frame-pane} {frame pane \key force-p}

Causes the pane \arg{pane} within the \term{frame} \arg{frame} to be redisplayed
immediately.  \arg{pane} is either a pane or the name of a named pane.  When the
boolean \arg{force-p} is \term{true}, the maximum level of redisplay is forced
(that is, the pane is displayed ``from scratch'').

\Defgeneric {redisplay-frame-panes} {frame \key force-p}

\cl{redisplay-frame-panes} causes all of the panes in the \term{frame}
\arg{frame} to be redisplayed immediately by calling \cl{redisplay-frame-pane}
on each of the panes in \arg{frame} that are visible in the current layout.
When the boolean \arg{force-p} is \term{true}, the maximum level of redisplay is
forced (that is, the pane is displayed ``from scratch'').

\Defgeneric {frame-replay} {frame stream \optional region}

Replays the contents of \arg{stream} in the \term{frame} \arg{frame} within the
region specified by the region \arg{region}, which defaults to viewport of
\arg{stream}.


\Defgeneric {notify-user} {frame message
                           \key associated-window title documentation
                                exit-boxes name style text-style}

Notifies the user of some event on behalf of the \term{frame} \arg{frame}.
\arg{message} is a message string.  This function provides a look and feel
independent way for applications to communicate messages to the user.

\arg{associated-window} is the window with which the notification will be
associated, as it is for \cl{menu-choose}.  \arg{title} is a title string to
include in the notification.  \arg{text-style} is the text style in which to
display the notification.  \arg{exit-boxes} is as for \arg{accepting-values}; it
indicates what sort of exit boxes should appear in the notification.
\arg{style} is the style in which to display the notification, and is
implementation-dependent.


\defgeneric {frame-properties} {frame property}
\Defgeneric {(setf frame-properties)} {value frame property}

Frame properties can be used to associate frame specific data with frames
without adding additional slots to the frame's class.  CLIM may use frame
properties internally to store information for its own purposes.


\subsection {Interface with Presentation Types}

This section describes the functions that connect application frames to the
presentation type system.  All classes that inherit from \cl{application-frame}
must inherit or implement methods for all of these functions.

\Defgeneric {frame-maintain-presentation-histories} {frame}

Returns \term{true} if the \term{frame} \arg{frame} maintains histories for its
presentations, otherwise returns \term{false}.  The default method (on
\cl{standard-application-frame}) returns \term{true} if and only if the frame
has at least one interactor pane.


\Defgeneric {frame-find-innermost-applicable-presentation} {frame input-context stream x y \key event}

Locates and returns the innermost applicable presentation on the window
\arg{stream} whose sensitivity region contains the point $(x,y)$, on behalf of
the \term{frame} \arg{frame} in the input context \arg{input-context}.
\arg{event} defaults to \cl{nil}, and is as for
{find-innermost-applicable-presentation}

The default method (on \cl{standard-application-frame}) will simply call
\cl{find-innermost-applicable-presentation}.

\Defgeneric {frame-input-context-button-press-handler} {frame stream button-press-event}

This function is responsible for handling user pointer events on behalf of the
\term{frame} \arg{frame} in the input context \cl{*input-context*}.
\arg{stream} is the window on which \arg{button-press-event} took place.

The default implementation (on \cl{standard-application-frame}) unhighlights any
highlighted presentations, finds the applicable presentation by calling
\cl{frame-find-innermost-applicable-presentation-at-position}, and then calls
\cl{throw-highlighted-presentation} to execute the translator on that
presentation that corresponds to the user's gesture.

If \cl{frame-input-context-button-press-handler} is called when the pointer is
not over any applicable presentation, \cl{throw-highlighted-presentation} must
be called with a presentation of \cl{*null-presentation*}.


\Defgeneric {frame-document-highlighted-presentation} {frame presentation input-context window x y stream}

This function is responsible for producing pointer documentation on behalf of
the \term{frame} \arg{frame} in the input context \arg{input-context} on the
window \arg{window} at the point $(x,y)$.  The documentation is displayed on the
\term{stream} \arg{stream}.

The default method (on \cl{standard-application-frame}) should produce
documentation that corresponds to calling \cl{document-presentation-translator}
on all of the applicable translators in the input context \arg{input-context}.
\arg{presentation}, \arg{window}, \arg{x}, \arg{y}, and \arg{stream} are as for
\cl{document-presentation-translator}.

Typically pointer documentation will consist of a brief description of each
translator that is applicable to the specified presentation in the specified
input context given the current modifier state for the window.  For example, the
following documentation might be produced when the pointer is pointing to a Lisp
expression when the input context is \cl{form}:

\begin{verbatim}
Left: '(1 2 3); Middle: (DESCRIBE '(1 2 3)); Right: Menu
\end{verbatim}


\Defgeneric {frame-drag-and-drop-feedback} {frame presentation stream
                                            initial-x initial-y new-x new-y state}

The default feedback function for translators defined by
\cl{define-drag-and-drop-translator}, which provides visual feedback during the
dragging phase of such translators on behalf of the \term{frame} \arg{frame}.
\arg{presentation} is the presentation being dragged on the stream \arg{stream}.
The pointing device was initially at the position specified by \arg{initial-x}
and \arg{initial-y}, and is at the position specified by \arg{new-x} and
\arg{new-y} when \cl{frame-drag-and-drop-feedback} is invoked.  (Both positions
are supplied for ``rubber-banding'', if that is the sort of desired feedback.)
\arg{state} will be either \cl{:highlight}, meaning that the feedback should be
drawn, or \cl{:unhighlight}, meaning that the feedback should be erased.

\Defgeneric {frame-drag-and-drop-highlighting} {frame presentation stream state}

The default highlighting function for translators defined by
\cl{define-drag-and-drop-translator}, which is invoked when a ``to object''
should be highlighted during the dragging phase of such translators on behalf of
the \term{frame} \arg{frame}.  \arg{presentation} is the presentation over which
the pointing device is located on the stream \arg{stream}.  \arg{state} will be
either \cl{:highlight}, meaning that the highlighting for the presentation
should be drawn, or \cl{:unhighlight}, meaning that the highlighting should be
erased.


\section {The Generic Command Loop}

The default application command loop provided by CLIM performs the following
steps:

\begin{enumerate}
\item Prompts the user for input.

\item Reads a command.  Each application frame has a command table that contains
those commands that the author of the application wishes to allow the user to
invoke at a given time.  Since commands may be read in any number of ways, the
generic command loop enforces no particular interface style.

\item Executes the command.  The definition of each command may refer to (and
update) the state variables of the frame, to which \cl{*application-frame*} will
be bound.

\item Runs the display function for each pane in the frame as necessary.  The
display function may refer to the frame's state variables.  Display functions
are usually written by the application writer, although certain display
functions are supplied by CLIM itself.  Note that an application frame is free
to have no panes.
\end{enumerate}


\Issue {SWM} {RWK has a reasonable proposal for breaking down command loops into
their component pieces.  It should be integrated here.}

All classes that inherit from \cl{application-frame} must inherit or implement
methods for all of the following functions.


\Defgeneric {run-frame-top-level} {frame \key \allow}

Runs the top-level function for the \term{frame} \arg{frame}.  The default
method on \cl{application-frame} simply invokes the top-level function for the
frame (which defaults to \cl{default-frame-top-level}).

\Defaroundmethod {run-frame-top-level} {(frame \cl{application-frame}) \key}

The \cl{:around} method of \cl{run-frame-top-level} on the
\cl{application-frame} class is responsible for establish the initial dynamic
bindings for the application, including (but not limited to) binding
\cl{*application-frame*} to \arg{frame}, binding \cl{*input-context*} to
\cl{nil}, resetting the delimiter and activation gestures, and binding
\cl{*input-wait-test*}, \cl{*input-wait-handler*}, and
\cl{*pointer-button-press-handler*} to \cl{nil}.


\Defgeneric {default-frame-top-level} {frame \key command-parser command-unparser
                                                  partial-command-parser
                                                  prompt}

The default top-level function for application frames.  This function implements
a ``read-eval-print'' loop that displays a prompt, calls
\cl{read-frame-command}, then calls \cl{execute-frame-command}, and finally
redisplays all of the panes that need to be redisplayed.

\cl{default-frame-top-level} will also establish a simple restart for
\cl{abort}, and bind the standard stream variables as follows.
\cl{*standard-input*} will be bound to the value returned by
\cl{frame-standard-input}.  \cl{*standard-output*} will be bound to the value
returned by \cl{frame-standard-output}.  \cl{*query-io*} will be bound to the
value returned by \cl{frame-query-io}.  \cl{*error-output*} will be bound to the
value returned by \cl{frame-error-output}.  It is unspecified what
\cl{*terminal-io*}, \cl{*debug-io*}, and \cl{*trace-output*} will be bound to.

\arg{prompt} is either a string to use as the prompt (defaulting to
\cl{"Command: "}), or a function of two arguments, a stream and the frame.

\arg{command-parser}, \arg{command-unparser}, and \arg{partial-command-parser}
are the same as for \cl{read-command}.  \arg{command-parser} defaults to
\cl{command-line-command-parser} if there is an interactor, otherwise it
defaults to \cl{menu-only-command-parser}.  \arg{command-unparser} defaults to
\cl{command-line-command-unparser}.  \arg{partial-command-parser} defaults to
\cl{command-line-read-remaining-arguments-for-partial-command} if there is an
interactor, otherwise it defaults to
\cl{menu-only-read-remaining-arguments-for-partial-command}.
\cl{default-frame-top-level} binds \cl{*command-parser*},
\cl{*command-unparser*}, and \cl{*partial-command-parser*} to the values of
\arg{command-parser}, \arg{command-unparser}, and \arg{partial-command-parser}.


\Defgeneric {read-frame-command} {frame \key (stream \cl{*standard-input*})}

Reads a command from the stream \arg{stream} on behalf of the \term{frame}
\arg{frame}.  The returned value is a command object.

The default method (on \cl{standard-application-frame}) for
\cl{read-frame-command} simply calls \cl{read-command}, supplying \arg{frame}'s
current command table as the command table.

\Defgeneric {execute-frame-command} {frame command}

Executes the command \arg{command} on behalf of the \term{frame} \arg{frame}.
\arg{command} is a command object, that is, a cons of a command name and a list
of the command's arguments.

The default method (on \cl{standard-application-frame}) for
\cl{execute-frame-command} simply applies the \cl{command-name} of \arg{command}
to \cl{command-arguments} of \arg{command}.

If process that \cl{execute-frame-command} is invoked in is not the same process
the one \arg{frame} is running in, CLIM may need to make special provisions in
order for the command to be correctly executed, since as queueing up a special
``command event'' in \arg{frame}'s event queue.  The exact details of how this
should work is left unspecified.


\Defgeneric {command-enabled} {command-name frame}

Returns \term{true} if the command named by \arg{command-name} is presently
enabled in the \term{frame} \arg{frame}, otherwise returns \term{false}.  If
\arg{command-name} is not accessible to the command table being used by
\arg{frame}, \cl{command-enabled} returns \term{false}.

Whether or not a particular command is currently enabled is stored independently
for each instance of an application frame; this status can vary between frames
that share a single command table.

\Defgeneric {(setf command-enabled)} {enabled command-name frame}

If \arg{enabled} is \term{false}, this disables the use of the command named by
\arg{command-name} while in the \term{frame} \arg{frame}.  Otherwise if
\arg{enabled} is \term{true}, the use of the command is enabled.  After the
command has been enabled (or disabled), \cl{note-command-enabled} (or
\cl{note-command-disabled}) is invoked on the frame manager and the frame in
order to update the appearance of the interface, for example, ``graying out'' a
disabled command.

If \arg{command-name} is not accessible to the command table being used by
\arg{frame}, using \cl{setf} on \cl{command-enabled} does nothing.


\Defgeneric {display-command-menu} {frame stream
                                    \key command-table initial-spacing row-wise
                                         max-width max-height n-rows n-columns
                                         (cell-align-x \cl{:left}) (cell-align-y \cl{:top})}

Displays the menu associated with the specified command table on \arg{stream} by
calling \cl{display-command-table-menu}.  If \arg{command-table} is not
supplied, it defaults to \cl{(frame-command-table \arg{stream})}.  This function
is generally used as the display function for panes that contain command menus.

\arg{initial-spacing}, \arg{max-width}, \arg{max-height}, \arg{n-rows},
\arg{n-columns}, \arg{row-wise}, \arg{cell-align-x}, and \arg{cell-align-y} are
as for \cl{formatting-item-list}.


\section {Frame Managers}

Frames may be \concept{adopted} by a frame manager, which involves invoking a
protocol for generating the pane hierarchy of the frame.  This protocol provides
for selecting pane types for abstract gadget panes based on the style
requirements imposed by the frame manager.  That is, the frame manager is
responsible for the ``look and feel'' of a frame.

After a frame is adopted it can be in any of the three following states:
\concept{enabled}, \concept{disabled}, or \concept{shrunk}.  An enabled frame is
visible unless it is occluded by other frames or the user is browsing outside of
the portion of the frame manager's space that the frame occupies.  A shrunken
frame provides a cue or handle for the frame, but generally will not show the
entire contents of the frame.  For example, the frame may be iconified or an
item for the frame may be placed in a special suspended frame menu.  A disabled
frame is not visible, nor is there any user accessible handle for enabling the
frame.

Frames may also be \concept{disowned}, which involves releasing the frame's
panes as well as all associated foreign resources.

\Defprotoclass {frame-manager}

The protocol class that corresponds to a frame manager.
\IfYouWantClass {a} {frame manager} {frame-manager}

There are no advertised standard frame manager classes.  Each port will
implement one or more frame managers that correspond to the look and feel for
the port.

\Defpredicate {frame-manager-p} {object}

Returns \term{true} if \arg{object} is a \term{frame manager}, otherwise returns
\term{false}.

\Defclass {standard-frame-manager}

The instantiable standard class that implements a frame manager. By default,
most frame manager classes will inherit from this class and specialize the host
window manager integrations when available.


\subsection {Finding Frame Managers}

Most frames need only deal directly with frame managers to the extent that they
need to find a frame manager into which they can insert themselves.  Since
frames will usually be invoked by some user action that is handled by some frame
manager, finding an appropriate frame manager is usually straightforward.

Some frames will support the embedding of other frames within themselves.  Such
frames would not only use frames but also act as frame managers, so that other
frames could insert frames.  In this case, the embedded frames are mostly
unaware that they are nested within other frames, but only know that they are
controlled by a particular frame manager.

\issue {SWM} {How does one write a frame that supports an embedded frame, such
as an editor frame within a documentation-writing frame?}

The \cl{find-frame-manager} function provides a flexible means for locating an
frame manager to adopt an application's frames into.  There are a variety of
ways that the user or the application can influence where an application's frame
is adopted.

An application can establish an application default frame manager using
\cl{with-frame-manager}.  A frame's top-level loop automatically establishes the
frame's frame manager.

The programmer or user can influence what frame manager is found by setting
\cl{*default-frame-manager*} or \cl{*default-server-path*}.

Each frame manager is associated with one specific port.  However, a single port
may have multiple frame managers managing various frames associated with the
port.


\Defun {find-frame-manager} {\rest options \key port \allow}

Finds an appropriate frame manager that conforms to the options, including the
\arg{port} argument.  Furthermore, CLIM applications may set up dynamic contexts
that affect what \cl{find-frame-manager} will return.

\arg{port} defaults to the value returned by \cl{find-port} applied to the remaining options.

A frame manager is found using the following rules in the order listed:

\begin{enumerate}
\item If a current frame manager has been established via an invocation of
\cl{with-frame-manager}, as is the case within a frame's top-level, and that
frame manager conforms to the options, it is returned.  The exact definition of
``conforming to the options'' varies from one port to another, but it may
include such things as matching the console number, color or resolution
properties, and so forth.  If the options are empty, then any frame manager will
conform.

\item If \cl{*default-frame-manager*} is bound to a currently active frame
manager and it conforms to the options, it is returned.

\item If \arg{port} is \cl{nil}, a port is found and an appropriate
frame manager is constructed using \cl{*default-server-path*}.
\end{enumerate}


\Defvar {*default-frame-manager*}

This variable provides a convenient point for allowing a programmer or user to
override what frame manager type would normally be selected.  Most users will
not set this variable since they can set \cl{*default-server-path*} to indicate
which host window system they want to use and are willing to use whatever frame
manager is the default for the particular port.  However, some users may want to
use a frame manager that isn't the typical frame manager.  For example, a user
may want to use both an OpenLook frame manager and a Motif frame manager on a
single port.

\Defmacro {with-frame-manager} {(frame-manager) \body body}

Generates a dynamic context that causes all calls to \cl{find-frame-manager} to
return \arg{frame-manager} if the \arg{where} argument passed to it conforms to
\arg{frame-manager}.  Nested calls to \cl{with-frame-manager} will shadow outer
contexts.  \arg{body} may have zero or more declarations as its first forms.


\subsection {Frame Manager Operations}

\Defgeneric {frame-manager} {frame}

Returns the current frame manager of \arg{frame} if it is adopted, otherwise
returns \cl{nil}.

\Defgeneric {(setf frame-manager)} {frame-manager frame}

Changes the frame manager of \arg{frame} to \arg{frame-manager}.  In effect, the
frame is disowned from its old frame manager and is adopted into the new frame
manager.  Transferring a frame preserves its \cl{frame-state}, for example, if
the frame was previously enabled it will be enabled in the new frame manager.

\Defgeneric {frame-manager-frames} {frame-manager}

Returns a list of all of the frames being managed by \arg{frame-manager}.
\ReadOnly

\defgeneric {adopt-frame} {frame-manager frame}
\Defgeneric {disown-frame} {frame-manager frame}

These functions insert or remove a frame from a frame manager's control.  These
functions allow a frame manager to allocate and deallocate resources associated
with a frame.  For example, removing a frame from a frame manager that is
talking to a remote server allows it to release all remote resources used by the
frame.

\Defmethod {port} {(frame \cl{standard-application-frame})}

If \arg{frame} has been adopted by a frame manager, this returns the port with
which \arg{frame} is associated.  Otherwise it returns \cl{nil}.

\Defmethod {port} {(frame-manager \cl{standard-frame-manager})}

Returns the port with which \arg{frame-manager} is associated.

\Defgeneric {frame-state} {frame}

Returns one of \cl{:disowned}, \cl{:enabled}, \cl{:disabled}, or \cl{:shrunk},
indicating the current state of frame.

\defgeneric {enable-frame} {frame}
\defgeneric {disable-frame} {frame}
\Defgeneric {shrink-frame} {frame}

These functions force a frame into the enabled, disabled, or shrunken
(iconified) states.  A frame in the enabled state may be visible if it is not
occluded or placed out of the user's focus of attention.  A disabled frame is
never visible.  A shrunk frame is accessible to the user for re-enabling, but
may be represented in some abbreviated form, such as an icon or a menu item.

These functions call the notification functions describe below to notify the
frame manager that the state of the frame changed.

\defgeneric {note-frame-enabled} {frame-manager frame}
\defgeneric {note-frame-disabled} {frame-manager frame}
\defgeneric {note-frame-iconified} {frame-manager frame}
\Defgeneric {note-frame-deiconified} {frame-manager frame}

Notifies the frame manager \arg{frame-manager} that the frame \arg{frame} has
changed its state to the enabled, disabled, iconified, or deiconified state,
respectively.


\defgeneric {note-command-enabled} {frame-manager frame command-name}
\Defgeneric {note-command-disabled} {frame-manager frame command-name}

Notifies the frame manager \arg{frame-manager} that the command named by
\arg{command-name} has been enabled or disabled (respectively) in the frame
\arg{frame}.  The frame manager can update the appearance of the user interface
as appropriate, for instance, by ``graying out'' a newly disabled command from a
command menu or menu bar.


\Defgeneric {frame-manager-notify-user} {framem message-string
                                         \key frame associated-window title documentation
                                              exit-boxes name style text-style}

This is the generic function used by \cl{notify-user}.  The arguments are as for
\cl{notify-user}.  The default method on \cl{standard-frame-manager} will
display a dialog or an alert box that contains the message and has exit boxes
that allow the user to dismiss the notification.


\Defgeneric {generate-panes} {frame-manager frame}

This function is invoked by a standard method of \cl{adopt-frame}.
\cl{define-application-frame} automatically supplies a \cl{generate-panes}
method if either the \cl{:pane} or \cl{:panes} option is used in the
\cl{define-application-frame}.

It is the responsibility of this method to call \cl{setf} on \cl{frame-panes} on
the frame in order to set the current

\Defgeneric {find-pane-for-frame} {frame-manager frame}

This function is invoked by a standard method of \cl{adopt-frame}.  It must
return the root pane of the frame's layout.  It is the responsibility of the
frame implementor to provide a method that constructs the frame's top-level
pane.  \cl{define-application-frame} automatically supplies a a method for this
function if either the \cl{:pane} or \cl{:panes} option is used in the
\cl{define-application-frame}.


\subsection {Frame Manager Settings}

CLIM provides frame manager settings in order to allow a frame to communicate
information to its frame manager.

\Defgeneric {(setf client-setting)} {value frame setting}

Sets the setting \arg{setting} to \arg{value} for the frame \arg{frame}.

\Defgeneric {reset-frame} {frame \rest client-settings}

Resets the settings of frame.  \cl{reset-frame} invokes a protocol that forces
the frame manager to notice that the settings have changed, where the setf
generic function just updates the frame data.  For example, the width and height
can be reset to force resizing of the window.


\newpage
\section {Examples of Applications}

The following is an example that outlines a simple 4-by-4 sliding piece puzzle:

\begin{verbatim}
(define-application-frame puzzle ()
    ((puzzle-array :initform (make-array '(4 4))))
  (:menu-bar t)
  (:panes
    (display
      (outlining ()
        (make-pane 'application-pane
                   :text-cursor nil
                   :width :compute
                   :height :compute
                   :incremental-redisplay T
                   :display-function 'draw-puzzle))))
  (:layouts
    (:default display)))

(defmethod run-frame-top-level :before ((puzzle puzzle))
  ;; Initialize the puzzle
  ...)

(define-presentation-type puzzle-cell ()
  :inherit-from '(integer 1 15))

(defmethod draw-puzzle ((puzzle puzzle) stream &key max-width max-height)
  (declare (ignore max-width max-height))
  ;; Draw the puzzle, presenting each cell as a PUZZLE-CELL
  ...)

(define-puzzle-command com-move-cell
    ((cell 'puzzle-cell :gesture :select))
  ;; Move the selected cell to the adjacent open cell,
  ;; if there is one
  ...)

(define-puzzle-command (com-scramble :menu t)
    ()
  ;; Scramble the pieces of the puzzle
  ...)

(define-puzzle-command (com-exit-puzzle :menu "Exit")
    ()
  (frame-exit *application-frame*))

(defun puzzle ()
  (let ((puzzle
          (make-application-frame 'puzzle
            :width 80 :height 80)))
    (run-frame-top-level puzzle)))
\end{verbatim}

The following is an application frame with two layouts:

\begin{verbatim}
(define-application-frame test-frame () ()
  (:panes
    (a (horizontally ()
         (make-pane 'push-button :label "Press me")
         (make-pane 'push-button :label "Squeeze me")))
    (b toggle-button)
    (c slider)
    (d text-field)
    (e :interactor-pane
       :width 300 :max-width +fill+
       :height 300 :max-height +fill+))
  (:layouts
    (default
      (vertically ()
        a b c (scrolling () e)))
    (other
      (vertically ()
        a (scrolling () e) b d))))

(define-test-frame-command (com-switch :name t :menu t)
    ()
  (setf (frame-current-layout *application-frame*)
        (ecase (frame-current-layout *application-frame*)
          (default other)
          (other default))))

(let ((test-frame
        (make-application-frame 'test-frame)))
  (run-frame-top-level test-frame))
\end{verbatim}
